#pragma once

#include<cstdio>
#include<ctime>
#include<cassert>
#include<cerrno>
#include<cstdlib>
#include<cstdarg>

#define DEBUG 0
#define NOTICE 1
#define WARINING 2
#define FATAL 3

const char* log_level[]={"DEBUG","NOTICE","WARINING","FATAL"};
void logMessage(int level,const char* format,...)
{
    assert(level>=DEBUG);
    assert(level<=FATAL);

    char* name=getenv("USER");
    char logBuffer[1024];
    va_list ap;
    va_start(ap,format);
    vsnprintf(logBuffer,sizeof(logBuffer)-1,format,ap);
    va_end(ap);

    FILE* out=(level==FATAL)? stderr:stdout;
    time_t tm = time(nullptr);
    struct tm* localTm=localtime(&tm);

    char timeStr[26]; // 考虑到asctime函数返回的字符串自带换行符，为了打印出来好看，下面手动去除这个换行符
    snprintf(timeStr, sizeof(timeStr), "%s", asctime(localTm));
    timeStr[strcspn(timeStr, "\n")] = 0; // Remove trailing newline
   
    fprintf(out,"%s | %s | %s | %s\n",
            log_level[level],
            timeStr,
            name==nullptr?"unknow":name,
            logBuffer);
}
